package pinboard.dataLayer.potocol.op;

import android.support.annotation.Nullable;

import com.google.gson.Gson;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;

import pinboard.dataLayer.CommHelper;
import pinboard.dataLayer.potocol.instructFormat.response.KeepAliveResponse;
import pinboard.dataLayer.potocol.instructFormat.response.LoginResponse;
import pinboard.dataLayer.potocol.instructFormat.response.LoginResult;
import pinboard.dataLayer.potocol.instructFormat.BizResponse;
import pinboard.dataLayer.potocol.instructFormat.Notification;
import pinboard.dataLayer.potocol.instructFormat.Response;
import pinboard.dataLayer.potocol.instructFormat.ServerMessage;

public class InstructClientDecoder {

    private static HashMap<String, Class<?>> responseResultMap = new HashMap<>();

    public static LoginResponse decodeToLoginResponse(byte[] bag) throws UnsupportedEncodingException {
        return decodeToBizResponse(bag, "Login2", LoginResult.class, LoginResponse.class);
    }

    public static KeepAliveResponse decodeToKeepAliveResponse(byte[] bag) throws UnsupportedEncodingException {
        return decodeToBizResponse(bag, "KeepAlive", String.class, KeepAliveResponse.class);
    }

    @Nullable
    static <T, R extends BizResponse<T>> R decodeToBizResponse(byte[] bag, String method, Class<T> resultClass, Class<R> responseClass) throws UnsupportedEncodingException {
        String msgStr = new String(bag, "utf8");
        Gson gson = new Gson();
        if (msgStr.contains(method)) {
            Response response = gson.fromJson(msgStr, Response.class);
            if (response.method.equals(method)) {
                R returnObj = gson.fromJson(msgStr, responseClass);
                returnObj.result = gson.fromJson(response.result, resultClass);
                return returnObj;
            }
        }
        return null;
    }

    public static ServerMessage decode(byte[] bag) throws UnsupportedEncodingException {
        String msgStr = new String(bag, "utf8");
        Gson gson = new Gson();
        ServerMessage sm = gson.fromJson(msgStr, ServerMessage.class);
        return decodeToSubServerMessage(sm, msgStr);
    }

    private static ServerMessage decodeToSubServerMessage(ServerMessage sm, String msgStr) {
        Gson gson = new Gson();
        if (sm.mType == 1) {
            Response response = gson.fromJson(msgStr, Response.class);
            return response;
        } else if (sm.mType == 2) {
            Notification notification = gson.fromJson(msgStr, Notification.class);
            return NotificationDecoder.decode(notification, msgStr);
        }
        return sm;
    }

    public static void decode(byte[] bag, InstructClientDecodeListener listener) {
        ServerMessage serverMessage = null;
        try {
            serverMessage = decode(bag);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            listener.onUnsupportedEncodingError(bag);
        }

        if (serverMessage.mType == 1) {
            Response response = CommHelper.as(serverMessage, Response.class);
            if (response != null) {
                ResponseDecoder.filter(response, listener);
            }
        } else if (serverMessage.mType == 2) {
            Notification notification = CommHelper.as(serverMessage, Notification.class);
            if (notification != null) {
                NotificationDecoder.filter(notification, listener);
            }
        }
    }
}

/*

    class Gen<T>{
        public T Data;
    }

    Object getData() {
        Class<?> my = nTypeMap.get("typename");//动态的，从一个字典得到一个类型

        //return new Response<my>();//我知道这样写是错的，能否告诉我这里怎么写？
        return create(my);
    }

    <T> Gen<T> create(Class<T> type) {
        return new Gen<T>();
    }



    Object getData() {
        Class<?> my = nTypeMap.get("typename");//动态的，从一个字典得到一个类型

        //return new Response<my>();//我知道这样写是错的，能否告诉我这里怎么写？

        return create(my);
    }

    <T> Response<T> create(Class<T> type) {
        return new Response<T>();
    }*/

/*

    public static Object TestTTT() {
        String x = "{'MType':1,'Sequence':'outServer0','Method':'Login2','Status':true,'Error':'','ErrorCode':'0','Result':'{\\'AccessToken\\':\\'te001:e8e20dc3af43bae703a27da20ce5422f\\',\\'SecretToken\\':null,\\'UserID\\':\\'te001\\',\\'DisplayName\\':\\'PiN管理員\\',\\'EMail\\':\\'1234@foxconn.com\\',\\'PhoneNo\\':\\'18523362842\\',\\'MeetingID\\':\\'\\',\\'MeetingPassword\\':null,\\'RoleName\\':\\'Admin\\',\\'TypeName\\':\\'Personal\\',\\'ExpiredTime\\':\\'2019-02-17 00:00:00\\',\\'JoinedMeetingID\\':null,\\'JoinedMeetingPassword\\':null,\\'AccountType\\':\\'WhiteBoard\\',\\'LoginStatus\\':\\'LoginNormal\\'}'}";
        x = x.replace('\'', '"');
        JsonParser parser = new JsonParser();  //创建json解析器
        JsonObject job = CommHelper.as(parser.parse(x), JsonObject.class);
        return decodeToBizClass(job);
    }*/

/*
    String x = "{'MType':1,'Sequence':'outServer0','Method':'Login2','Status':true,'Error':'','ErrorCode':'0','Result':'{\\'AccessToken\\':\\'te001:e8e20dc3af43bae703a27da20ce5422f\\',\\'SecretToken\\':null,\\'UserID\\':\\'te001\\',\\'DisplayName\\':\\'PiN管理員\\',\\'EMail\\':\\'1234@foxconn.com\\',\\'PhoneNo\\':\\'18523362842\\',\\'MeetingID\\':\\'\\',\\'MeetingPassword\\':null,\\'RoleName\\':\\'Admin\\',\\'TypeName\\':\\'Personal\\',\\'ExpiredTime\\':\\'2019-02-17 00:00:00\\',\\'JoinedMeetingID\\':null,\\'JoinedMeetingPassword\\':null,\\'AccountType\\':\\'WhiteBoard\\',\\'LoginStatus\\':\\'LoginNormal\\'}'}";
x = x.replace('\'', '"');
        JsonParser parser = new JsonParser();  //创建json解析器
        JsonObject job = CommHelper.as(parser.parse(x), JsonObject.class);
        if (job != null) {
        int s = 1;
        s = s + 3;
        }*/

/*


try {
        Response<MeetingState> testObj1 = InstructClientDecoder.decodeToLoginResult(null);
        MeetingState lr222 = testObj1.result;

        } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        }
        catch (Exception ee){
        ee.printStackTrace();
        }


        Response<LoginResponseData> testObj = (Response<LoginResponseData>) InstructClientDecoder.TestTTT();

        LoginResponseData lr = testObj.result;*/


/*

    String x = "{'MType':1,'Sequence':'outServer0','Method':'Login2','Status':true,'Error':'','ErrorCode':'0','Result':'{\\'AccessToken\\':\\'te001:e8e20dc3af43bae703a27da20ce5422f\\',\\'SecretToken\\':null,\\'UserID\\':\\'te001\\',\\'DisplayName\\':\\'PiN管理員\\',\\'EMail\\':\\'1234@foxconn.com\\',\\'PhoneNo\\':\\'18523362842\\',\\'MeetingID\\':\\'\\',\\'MeetingPassword\\':null,\\'RoleName\\':\\'Admin\\',\\'TypeName\\':\\'Personal\\',\\'ExpiredTime\\':\\'2019-02-17 00:00:00\\',\\'JoinedMeetingID\\':null,\\'JoinedMeetingPassword\\':null,\\'AccountType\\':\\'WhiteBoard\\',\\'LoginStatus\\':\\'LoginNormal\\'}'}";
x = x.replace('\'', '"');
        bag = x.short2Bytes();
*/
